using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Threading;
namespace Microsoft.Phone.Controls
{
	[ContentProperty("ItemsSource"), StyleTypedProperty(Property = "TextBoxStyle", StyleTargetType = typeof(TextBox)), StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(ListBox)), TemplatePart(Name = "Selector", Type = typeof(Selector)), TemplatePart(Name = "SelectionAdapter", Type = typeof(ISelectionAdapter)), TemplatePart(Name = "Text", Type = typeof(TextBox)), TemplatePart(Name = "Popup", Type = typeof(Popup)), TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates"), TemplateVisualState(Name = "Normal", GroupName = "CommonStates"), TemplateVisualState(Name = "PopupOpened", GroupName = "PopupStates"), TemplateVisualState(Name = "Valid", GroupName = "ValidationStates"), TemplateVisualState(Name = "InvalidFocused", GroupName = "ValidationStates"), TemplateVisualState(Name = "Disabled", GroupName = "CommonStates"), TemplateVisualState(Name = "Focused", GroupName = "FocusStates"), TemplateVisualState(Name = "PopupClosed", GroupName = "PopupStates"), TemplateVisualState(Name = "InvalidUnfocused", GroupName = "ValidationStates"), TemplateVisualState(Name = "Pressed", GroupName = "CommonStates"), TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates")]
	public class AutoCompleteBox : Control, IUpdateVisualState
	{
		private const string ElementSelectionAdapter = "SelectionAdapter";
		private const string ElementSelector = "Selector";
		private const string ElementPopup = "Popup";
		private const string ElementTextBox = "Text";
		private const string ElementTextBoxStyle = "TextBoxStyle";
		private const string ElementItemContainerStyle = "ItemContainerStyle";
		private List<object> _items;
		private ObservableCollection<object> _view;
		private int _ignoreTextPropertyChange;
		private bool _ignorePropertyChange;
		private bool _ignoreTextSelectionChange;
		private bool _skipSelectedItemTextUpdate;
		private int _textSelectionStart;
		private bool _inputtingText;
		private bool _userCalledPopulate;
		private bool _popupHasOpened;
		private DispatcherTimer _delayTimer;
		private bool _allowWrite;
		private BindingEvaluator<string> _valueBindingEvaluator;
		private WeakEventListener<AutoCompleteBox, object, NotifyCollectionChangedEventArgs> _collectionChangedWeakEventListener;
		public static readonly DependencyProperty MinimumPrefixLengthProperty = DependencyProperty.Register("MinimumPrefixLength", typeof(int), typeof(AutoCompleteBox), new PropertyMetadata(1, new PropertyChangedCallback(AutoCompleteBox.OnMinimumPrefixLengthPropertyChanged)));
		public static readonly DependencyProperty MinimumPopulateDelayProperty = DependencyProperty.Register("MinimumPopulateDelay", typeof(int), typeof(AutoCompleteBox), new PropertyMetadata(new PropertyChangedCallback(AutoCompleteBox.OnMinimumPopulateDelayPropertyChanged)));
		public static readonly DependencyProperty IsTextCompletionEnabledProperty = DependencyProperty.Register("IsTextCompletionEnabled", typeof(bool), typeof(AutoCompleteBox), new PropertyMetadata(false, null));
		public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(AutoCompleteBox), new PropertyMetadata(null));
		public static readonly DependencyProperty ItemContainerStyleProperty = DependencyProperty.Register("ItemContainerStyle", typeof(Style), typeof(AutoCompleteBox), new PropertyMetadata(null, null));
		public static readonly DependencyProperty TextBoxStyleProperty = DependencyProperty.Register("TextBoxStyle", typeof(Style), typeof(AutoCompleteBox), new PropertyMetadata(null));
		public static readonly DependencyProperty MaxDropDownHeightProperty = DependencyProperty.Register("MaxDropDownHeight", typeof(double), typeof(AutoCompleteBox), new PropertyMetadata(double.PositiveInfinity, new PropertyChangedCallback(AutoCompleteBox.OnMaxDropDownHeightPropertyChanged)));
		public static readonly DependencyProperty IsDropDownOpenProperty = DependencyProperty.Register("IsDropDownOpen", typeof(bool), typeof(AutoCompleteBox), new PropertyMetadata(false, new PropertyChangedCallback(AutoCompleteBox.OnIsDropDownOpenPropertyChanged)));
		public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(AutoCompleteBox), new PropertyMetadata(new PropertyChangedCallback(AutoCompleteBox.OnItemsSourcePropertyChanged)));
		public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(AutoCompleteBox), new PropertyMetadata(new PropertyChangedCallback(AutoCompleteBox.OnSelectedItemPropertyChanged)));
		public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(AutoCompleteBox), new PropertyMetadata(string.Empty, new PropertyChangedCallback(AutoCompleteBox.OnTextPropertyChanged)));
		public static readonly DependencyProperty SearchTextProperty = DependencyProperty.Register("SearchText", typeof(string), typeof(AutoCompleteBox), new PropertyMetadata(string.Empty, new PropertyChangedCallback(AutoCompleteBox.OnSearchTextPropertyChanged)));
		public static readonly DependencyProperty FilterModeProperty = DependencyProperty.Register("FilterMode", typeof(AutoCompleteFilterMode), typeof(AutoCompleteBox), new PropertyMetadata(AutoCompleteFilterMode.StartsWith, new PropertyChangedCallback(AutoCompleteBox.OnFilterModePropertyChanged)));
		public static readonly DependencyProperty ItemFilterProperty = DependencyProperty.Register("ItemFilter", typeof(AutoCompleteFilterPredicate<object>), typeof(AutoCompleteBox), new PropertyMetadata(new PropertyChangedCallback(AutoCompleteBox.OnItemFilterPropertyChanged)));
		public static readonly DependencyProperty TextFilterProperty = DependencyProperty.Register("TextFilter", typeof(AutoCompleteFilterPredicate<string>), typeof(AutoCompleteBox), new PropertyMetadata(AutoCompleteSearch.GetFilter(AutoCompleteFilterMode.StartsWith)));
		public static readonly DependencyProperty InputScopeProperty = DependencyProperty.Register("InputScope", typeof(InputScope), typeof(AutoCompleteBox), null);
		private TextBox _text;
		private ISelectionAdapter _adapter;
		public event RoutedEventHandler TextChanged;
		public event PopulatingEventHandler Populating;
		public event PopulatedEventHandler Populated;
		public event RoutedPropertyChangingEventHandler<bool> DropDownOpening;
		public event RoutedPropertyChangedEventHandler<bool> DropDownOpened;
		public event RoutedPropertyChangingEventHandler<bool> DropDownClosing;
		public event RoutedPropertyChangedEventHandler<bool> DropDownClosed;
		public event SelectionChangedEventHandler SelectionChanged;
		internal InteractionHelper Interaction
		{
			get;
			set;
		}
		public int MinimumPrefixLength
		{
			get
			{
				return (int)base.GetValue(AutoCompleteBox.MinimumPrefixLengthProperty);
			}
			set
			{
				base.SetValue(AutoCompleteBox.MinimumPrefixLengthProperty, value);
			}
		}
		public int MinimumPopulateDelay
		{
			get
			{
				return (int)base.GetValue(AutoCompleteBox.MinimumPopulateDelayProperty);
			}
			set
			{
				base.SetValue(AutoCompleteBox.MinimumPopulateDelayProperty, value);
			}
		}
		public bool IsTextCompletionEnabled
		{
			get
			{
				return (bool)base.GetValue(AutoCompleteBox.IsTextCompletionEnabledProperty);
			}
			set
			{
				base.SetValue(AutoCompleteBox.IsTextCompletionEnabledProperty, value);
			}
		}
		public DataTemplate ItemTemplate
		{
			get
			{
				return base.GetValue(AutoCompleteBox.ItemTemplateProperty) as DataTemplate;
			}
			set
			{
				base.SetValue(AutoCompleteBox.ItemTemplateProperty, value);
			}
		}
		public Style ItemContainerStyle
		{
			get
			{
				return base.GetValue(AutoCompleteBox.ItemContainerStyleProperty) as Style;
			}
			set
			{
				base.SetValue(AutoCompleteBox.ItemContainerStyleProperty, value);
			}
		}
		public Style TextBoxStyle
		{
			get
			{
				return base.GetValue(AutoCompleteBox.TextBoxStyleProperty) as Style;
			}
			set
			{
				base.SetValue(AutoCompleteBox.TextBoxStyleProperty, value);
			}
		}
		public double MaxDropDownHeight
		{
			get
			{
				return (double)base.GetValue(AutoCompleteBox.MaxDropDownHeightProperty);
			}
			set
			{
				base.SetValue(AutoCompleteBox.MaxDropDownHeightProperty, value);
			}
		}
		public bool IsDropDownOpen
		{
			get
			{
				return (bool)base.GetValue(AutoCompleteBox.IsDropDownOpenProperty);
			}
			set
			{
				base.SetValue(AutoCompleteBox.IsDropDownOpenProperty, value);
			}
		}
		public IEnumerable ItemsSource
		{
			get
			{
				return base.GetValue(AutoCompleteBox.ItemsSourceProperty) as IEnumerable;
			}
			set
			{
				base.SetValue(AutoCompleteBox.ItemsSourceProperty, value);
			}
		}
		public object SelectedItem
		{
			get
			{
				return base.GetValue(AutoCompleteBox.SelectedItemProperty);
			}
			set
			{
				base.SetValue(AutoCompleteBox.SelectedItemProperty, value);
			}
		}
		public string Text
		{
			get
			{
				return base.GetValue(AutoCompleteBox.TextProperty) as string;
			}
			set
			{
				base.SetValue(AutoCompleteBox.TextProperty, value);
			}
		}
		public string SearchText
		{
			get
			{
				return (string)base.GetValue(AutoCompleteBox.SearchTextProperty);
			}
			private set
			{
				try
				{
					this._allowWrite = true;
					base.SetValue(AutoCompleteBox.SearchTextProperty, value);
				}
				finally
				{
					this._allowWrite = false;
				}
			}
		}
		public AutoCompleteFilterMode FilterMode
		{
			get
			{
				return (AutoCompleteFilterMode)base.GetValue(AutoCompleteBox.FilterModeProperty);
			}
			set
			{
				base.SetValue(AutoCompleteBox.FilterModeProperty, value);
			}
		}
		public AutoCompleteFilterPredicate<object> ItemFilter
		{
			get
			{
				return base.GetValue(AutoCompleteBox.ItemFilterProperty) as AutoCompleteFilterPredicate<object>;
			}
			set
			{
				base.SetValue(AutoCompleteBox.ItemFilterProperty, value);
			}
		}
		public AutoCompleteFilterPredicate<string> TextFilter
		{
			get
			{
				return base.GetValue(AutoCompleteBox.TextFilterProperty) as AutoCompleteFilterPredicate<string>;
			}
			set
			{
				base.SetValue(AutoCompleteBox.TextFilterProperty, value);
			}
		}
		public InputScope InputScope
		{
			get
			{
				return (InputScope)base.GetValue(AutoCompleteBox.InputScopeProperty);
			}
			set
			{
				base.SetValue(AutoCompleteBox.InputScopeProperty, value);
			}
		}
		private PopupHelper DropDownPopup
		{
			get;
			set;
		}
		private static bool IsCompletionEnabled
		{
			get
			{
				PhoneApplicationFrame phoneApplicationFrame;
				return PhoneHelper.TryGetPhoneApplicationFrame(out phoneApplicationFrame) && phoneApplicationFrame.IsPortrait();
			}
		}
		internal TextBox TextBox
		{
			get
			{
				return this._text;
			}
			set
			{
				if (this._text != null)
				{
					this._text.remove_SelectionChanged(new RoutedEventHandler(this.OnTextBoxSelectionChanged));
					this._text.remove_TextChanged(new TextChangedEventHandler(this.OnTextBoxTextChanged));
				}
				this._text = value;
				if (this._text != null)
				{
					this._text.add_SelectionChanged(new RoutedEventHandler(this.OnTextBoxSelectionChanged));
					this._text.add_TextChanged(new TextChangedEventHandler(this.OnTextBoxTextChanged));
					if (this.Text != null)
					{
						this.UpdateTextValue(this.Text);
					}
				}
			}
		}
		protected internal ISelectionAdapter SelectionAdapter
		{
			get
			{
				return this._adapter;
			}
			set
			{
				if (this._adapter != null)
				{
					this._adapter.SelectionChanged -= new SelectionChangedEventHandler(this.OnAdapterSelectionChanged);
					this._adapter.Commit -= new RoutedEventHandler(this.OnAdapterSelectionComplete);
					this._adapter.Cancel -= new RoutedEventHandler(this.OnAdapterSelectionCanceled);
					this._adapter.Cancel -= new RoutedEventHandler(this.OnAdapterSelectionComplete);
					this._adapter.ItemsSource = null;
				}
				this._adapter = value;
				if (this._adapter != null)
				{
					this._adapter.SelectionChanged += new SelectionChangedEventHandler(this.OnAdapterSelectionChanged);
					this._adapter.Commit += new RoutedEventHandler(this.OnAdapterSelectionComplete);
					this._adapter.Cancel += new RoutedEventHandler(this.OnAdapterSelectionCanceled);
					this._adapter.Cancel += new RoutedEventHandler(this.OnAdapterSelectionComplete);
					this._adapter.ItemsSource = this._view;
				}
			}
		}
		public Binding ValueMemberBinding
		{
			get
			{
				if (this._valueBindingEvaluator == null)
				{
					return null;
				}
				return this._valueBindingEvaluator.ValueBinding;
			}
			set
			{
				this._valueBindingEvaluator = new BindingEvaluator<string>(value);
			}
		}
		public string ValueMemberPath
		{
			get
			{
				if (this.ValueMemberBinding == null)
				{
					return null;
				}
				return this.ValueMemberBinding.get_Path().get_Path();
			}
			set
			{
				this.ValueMemberBinding = ((value == null) ? null : new Binding(value));
			}
		}
		private static void OnMinimumPrefixLengthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			int num = (int)e.get_NewValue();
			if (num < 0 && num != -1)
			{
				throw new ArgumentOutOfRangeException("MinimumPrefixLength");
			}
		}
		private static void OnMinimumPopulateDelayPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			AutoCompleteBox autoCompleteBox = d as AutoCompleteBox;
			if (autoCompleteBox._ignorePropertyChange)
			{
				autoCompleteBox._ignorePropertyChange = false;
				return;
			}
			int num = (int)e.get_NewValue();
			if (num < 0)
			{
				autoCompleteBox._ignorePropertyChange = true;
				d.SetValue(e.get_Property(), e.get_OldValue());
			}
			if (autoCompleteBox._delayTimer != null)
			{
				autoCompleteBox._delayTimer.Stop();
				if (num == 0)
				{
					autoCompleteBox._delayTimer = null;
				}
			}
			if (num > 0 && autoCompleteBox._delayTimer == null)
			{
				autoCompleteBox._delayTimer = new DispatcherTimer();
				autoCompleteBox._delayTimer.add_Tick(new EventHandler(autoCompleteBox.PopulateDropDown));
			}
			if (num > 0 && autoCompleteBox._delayTimer != null)
			{
				autoCompleteBox._delayTimer.set_Interval(TimeSpan.FromMilliseconds((double)num));
			}
		}
		private static void OnMaxDropDownHeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			AutoCompleteBox autoCompleteBox = d as AutoCompleteBox;
			if (autoCompleteBox._ignorePropertyChange)
			{
				autoCompleteBox._ignorePropertyChange = false;
				return;
			}
			double num = (double)e.get_NewValue();
			if (num < 0.0)
			{
				autoCompleteBox._ignorePropertyChange = true;
				autoCompleteBox.SetValue(e.get_Property(), e.get_OldValue());
			}
			autoCompleteBox.OnMaxDropDownHeightChanged(num);
		}
		private static void OnIsDropDownOpenPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			AutoCompleteBox autoCompleteBox = d as AutoCompleteBox;
			if (autoCompleteBox._ignorePropertyChange)
			{
				autoCompleteBox._ignorePropertyChange = false;
				return;
			}
			bool oldValue = (bool)e.get_OldValue();
			if ((bool)e.get_NewValue())
			{
				autoCompleteBox.TextUpdated(autoCompleteBox.Text, true);
			}
			else
			{
				autoCompleteBox.ClosingDropDown(oldValue);
			}
			autoCompleteBox.UpdateVisualState(true);
		}
		private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			AutoCompleteBox autoCompleteBox = d as AutoCompleteBox;
			autoCompleteBox.OnItemsSourceChanged((IEnumerable)e.get_OldValue(), (IEnumerable)e.get_NewValue());
		}
		private static void OnSelectedItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			AutoCompleteBox autoCompleteBox = d as AutoCompleteBox;
			if (autoCompleteBox._ignorePropertyChange)
			{
				autoCompleteBox._ignorePropertyChange = false;
				return;
			}
			if (autoCompleteBox._skipSelectedItemTextUpdate)
			{
				autoCompleteBox._skipSelectedItemTextUpdate = false;
			}
			else
			{
				autoCompleteBox.OnSelectedItemChanged(e.get_NewValue());
			}
			List<object> list = new List<object>();
			if (e.get_OldValue() != null)
			{
				list.Add(e.get_OldValue());
			}
			List<object> list2 = new List<object>();
			if (e.get_NewValue() != null)
			{
				list2.Add(e.get_NewValue());
			}
			autoCompleteBox.OnSelectionChanged(new SelectionChangedEventArgs(list, list2));
		}
		private void OnSelectedItemChanged(object newItem)
		{
			string value;
			if (newItem == null)
			{
				value = this.SearchText;
			}
			else
			{
				value = this.FormatValue(newItem, true);
			}
			this.UpdateTextValue(value);
			if (this.TextBox != null && this.Text != null)
			{
				this.TextBox.set_SelectionStart(this.Text.get_Length());
			}
		}
		private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			AutoCompleteBox autoCompleteBox = d as AutoCompleteBox;
			autoCompleteBox.TextUpdated((string)e.get_NewValue(), false);
		}
		private static void OnSearchTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			AutoCompleteBox autoCompleteBox = d as AutoCompleteBox;
			if (autoCompleteBox._ignorePropertyChange)
			{
				autoCompleteBox._ignorePropertyChange = false;
				return;
			}
			if (!autoCompleteBox._allowWrite)
			{
				autoCompleteBox._ignorePropertyChange = true;
				autoCompleteBox.SetValue(e.get_Property(), e.get_OldValue());
			}
		}
		private static void OnFilterModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			AutoCompleteBox autoCompleteBox = d as AutoCompleteBox;
			AutoCompleteFilterMode autoCompleteFilterMode = (AutoCompleteFilterMode)e.get_NewValue();
			if (autoCompleteFilterMode != AutoCompleteFilterMode.Contains && autoCompleteFilterMode != AutoCompleteFilterMode.ContainsCaseSensitive && autoCompleteFilterMode != AutoCompleteFilterMode.ContainsOrdinal && autoCompleteFilterMode != AutoCompleteFilterMode.ContainsOrdinalCaseSensitive && autoCompleteFilterMode != AutoCompleteFilterMode.Custom && autoCompleteFilterMode != AutoCompleteFilterMode.Equals && autoCompleteFilterMode != AutoCompleteFilterMode.EqualsCaseSensitive && autoCompleteFilterMode != AutoCompleteFilterMode.EqualsOrdinal && autoCompleteFilterMode != AutoCompleteFilterMode.EqualsOrdinalCaseSensitive && autoCompleteFilterMode != AutoCompleteFilterMode.None && autoCompleteFilterMode != AutoCompleteFilterMode.StartsWith && autoCompleteFilterMode != AutoCompleteFilterMode.StartsWithCaseSensitive && autoCompleteFilterMode != AutoCompleteFilterMode.StartsWithOrdinal && autoCompleteFilterMode != AutoCompleteFilterMode.StartsWithOrdinalCaseSensitive)
			{
				autoCompleteBox.SetValue(e.get_Property(), e.get_OldValue());
			}
			AutoCompleteFilterMode filterMode = (AutoCompleteFilterMode)e.get_NewValue();
			autoCompleteBox.TextFilter = AutoCompleteSearch.GetFilter(filterMode);
		}
		private static void OnItemFilterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			AutoCompleteBox autoCompleteBox = d as AutoCompleteBox;
			if (!(e.get_NewValue() is AutoCompleteFilterPredicate<object>))
			{
				autoCompleteBox.FilterMode = AutoCompleteFilterMode.None;
				return;
			}
			autoCompleteBox.FilterMode = AutoCompleteFilterMode.Custom;
			autoCompleteBox.TextFilter = null;
		}
		public AutoCompleteBox()
		{
			base.set_DefaultStyleKey(typeof(AutoCompleteBox));
			RoutedEventHandler routedEventHandler = delegate(object sender, RoutedEventArgs e)
			{
				base.ApplyTemplate();
			};
			base.add_Loaded(routedEventHandler);
			RoutedEventHandler routedEventHandler2 = delegate(object sender, RoutedEventArgs e)
			{
				PhoneApplicationFrame phoneApplicationFrame;
				if (PhoneHelper.TryGetPhoneApplicationFrame(out phoneApplicationFrame))
				{
					phoneApplicationFrame.add_OrientationChanged(delegate(object sender, OrientationChangedEventArgs e)
					{
						this.IsDropDownOpen = false;
					});
				}
			};
			base.add_Loaded(routedEventHandler2);
			base.add_IsEnabledChanged(new DependencyPropertyChangedEventHandler(this.ControlIsEnabledChanged));
			this.Interaction = new InteractionHelper(this);
			this.ClearView();
		}
		protected override Size ArrangeOverride(Size finalSize)
		{
			Size result = base.ArrangeOverride(finalSize);
			if (this.DropDownPopup != null)
			{
				this.DropDownPopup.Arrange(new Size?(finalSize));
			}
			return result;
		}
		public override void OnApplyTemplate()
		{
			if (this.TextBox != null)
			{
				this.TextBox.RemoveHandler(UIElement.KeyDownEvent, new KeyEventHandler(this.OnUIElementKeyDown));
				this.TextBox.RemoveHandler(UIElement.KeyUpEvent, new KeyEventHandler(this.OnUIElementKeyUp));
			}
			if (this.DropDownPopup != null)
			{
				this.DropDownPopup.Closed -= new EventHandler(this.DropDownPopup_Closed);
				this.DropDownPopup.FocusChanged -= new EventHandler(this.OnDropDownFocusChanged);
				this.DropDownPopup.UpdateVisualStates -= new EventHandler(this.OnDropDownPopupUpdateVisualStates);
				this.DropDownPopup.BeforeOnApplyTemplate();
				this.DropDownPopup = null;
			}
			base.OnApplyTemplate();
			Popup popup = base.GetTemplateChild("Popup") as Popup;
			if (popup != null)
			{
				this.DropDownPopup = new PopupHelper(this, popup);
				this.DropDownPopup.MaxDropDownHeight = this.MaxDropDownHeight;
				this.DropDownPopup.AfterOnApplyTemplate();
				this.DropDownPopup.Closed += new EventHandler(this.DropDownPopup_Closed);
				this.DropDownPopup.FocusChanged += new EventHandler(this.OnDropDownFocusChanged);
				this.DropDownPopup.UpdateVisualStates += new EventHandler(this.OnDropDownPopupUpdateVisualStates);
			}
			this.SelectionAdapter = this.GetSelectionAdapterPart();
			this.TextBox = (base.GetTemplateChild("Text") as TextBox);
			if (this.TextBox != null)
			{
				this.TextBox.AddHandler(UIElement.KeyDownEvent, new KeyEventHandler(this.OnUIElementKeyDown), true);
				this.TextBox.AddHandler(UIElement.KeyUpEvent, new KeyEventHandler(this.OnUIElementKeyUp), true);
			}
			this.Interaction.OnApplyTemplateBase();
			if (this.IsDropDownOpen && this.DropDownPopup != null && !this.DropDownPopup.IsOpen)
			{
				this.OpeningDropDown(false);
			}
		}
		private void OnDropDownPopupUpdateVisualStates(object sender, EventArgs e)
		{
			this.UpdateVisualState(true);
		}
		private void OnDropDownFocusChanged(object sender, EventArgs e)
		{
			this.FocusChanged(this.HasFocus());
		}
		private void ClosingDropDown(bool oldValue)
		{
			bool flag = false;
			if (this.DropDownPopup != null)
			{
				flag = this.DropDownPopup.UsesClosingVisualState;
			}
			RoutedPropertyChangingEventArgs<bool> routedPropertyChangingEventArgs = new RoutedPropertyChangingEventArgs<bool>(AutoCompleteBox.IsDropDownOpenProperty, oldValue, false, true);
			this.OnDropDownClosing(routedPropertyChangingEventArgs);
			if (this._view == null || this._view.get_Count() == 0)
			{
				flag = false;
			}
			if (routedPropertyChangingEventArgs.Cancel)
			{
				this._ignorePropertyChange = true;
				base.SetValue(AutoCompleteBox.IsDropDownOpenProperty, oldValue);
			}
			else
			{
				if (!flag)
				{
					this.CloseDropDown(oldValue, false);
				}
			}
			this.UpdateVisualState(true);
		}
		private void OpeningDropDown(bool oldValue)
		{
			if (!AutoCompleteBox.IsCompletionEnabled)
			{
				return;
			}
			RoutedPropertyChangingEventArgs<bool> routedPropertyChangingEventArgs = new RoutedPropertyChangingEventArgs<bool>(AutoCompleteBox.IsDropDownOpenProperty, oldValue, true, true);
			this.OnDropDownOpening(routedPropertyChangingEventArgs);
			if (routedPropertyChangingEventArgs.Cancel)
			{
				this._ignorePropertyChange = true;
				base.SetValue(AutoCompleteBox.IsDropDownOpenProperty, oldValue);
			}
			else
			{
				this.OpenDropDown(oldValue, true);
			}
			this.UpdateVisualState(true);
		}
		private void DropDownPopup_Closed(object sender, EventArgs e)
		{
			if (this.IsDropDownOpen)
			{
				this.IsDropDownOpen = false;
			}
			if (this._popupHasOpened)
			{
				this.OnDropDownClosed(new RoutedPropertyChangedEventArgs<bool>(true, false));
			}
		}
		private void FocusChanged(bool hasFocus)
		{
			if (hasFocus)
			{
				if (this.TextBox != null && this.TextBox.get_SelectionLength() == 0)
				{
					this.TextBox.Focus();
					return;
				}
			}
			else
			{
				this.IsDropDownOpen = false;
				this._userCalledPopulate = false;
			}
		}
		protected bool HasFocus()
		{
			DependencyObject parent;
			for (DependencyObject dependencyObject = FocusManager.GetFocusedElement() as DependencyObject; dependencyObject != null; dependencyObject = parent)
			{
				if (object.ReferenceEquals(dependencyObject, this))
				{
					return true;
				}
				parent = VisualTreeHelper.GetParent(dependencyObject);
				if (parent == null)
				{
					FrameworkElement frameworkElement = dependencyObject as FrameworkElement;
					if (frameworkElement != null)
					{
						parent = frameworkElement.get_Parent();
					}
				}
			}
			return false;
		}
		protected override void OnGotFocus(RoutedEventArgs e)
		{
			base.OnGotFocus(e);
			this.FocusChanged(this.HasFocus());
		}
		protected override void OnLostFocus(RoutedEventArgs e)
		{
			base.OnLostFocus(e);
			this.FocusChanged(this.HasFocus());
		}
		private void ControlIsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
		{
			if (!(bool)e.get_NewValue())
			{
				this.IsDropDownOpen = false;
			}
		}
		protected virtual ISelectionAdapter GetSelectionAdapterPart()
		{
			ISelectionAdapter selectionAdapter = null;
			Selector selector = base.GetTemplateChild("Selector") as Selector;
			if (selector != null)
			{
				selectionAdapter = (selector as ISelectionAdapter);
				if (selectionAdapter == null)
				{
					selectionAdapter = new SelectorSelectionAdapter(selector);
				}
			}
			if (selectionAdapter == null)
			{
				selectionAdapter = (base.GetTemplateChild("SelectionAdapter") as ISelectionAdapter);
			}
			return selectionAdapter;
		}
		private void PopulateDropDown(object sender, EventArgs e)
		{
			if (this._delayTimer != null)
			{
				this._delayTimer.Stop();
			}
			this.SearchText = this.Text;
			PopulatingEventArgs populatingEventArgs = new PopulatingEventArgs(this.SearchText);
			this.OnPopulating(populatingEventArgs);
			if (!populatingEventArgs.Cancel)
			{
				this.PopulateComplete();
			}
		}
		protected virtual void OnPopulating(PopulatingEventArgs e)
		{
			PopulatingEventHandler populating = this.Populating;
			if (populating != null)
			{
				populating(this, e);
			}
		}
		protected virtual void OnPopulated(PopulatedEventArgs e)
		{
			PopulatedEventHandler populated = this.Populated;
			if (populated != null)
			{
				populated(this, e);
			}
		}
		protected virtual void OnSelectionChanged(SelectionChangedEventArgs e)
		{
			SelectionChangedEventHandler selectionChanged = this.SelectionChanged;
			if (selectionChanged != null)
			{
				selectionChanged.Invoke(this, e);
			}
		}
		protected virtual void OnDropDownOpening(RoutedPropertyChangingEventArgs<bool> e)
		{
			RoutedPropertyChangingEventHandler<bool> dropDownOpening = this.DropDownOpening;
			if (dropDownOpening != null)
			{
				dropDownOpening(this, e);
			}
		}
		protected virtual void OnDropDownOpened(RoutedPropertyChangedEventArgs<bool> e)
		{
			RoutedPropertyChangedEventHandler<bool> dropDownOpened = this.DropDownOpened;
			if (dropDownOpened != null)
			{
				dropDownOpened.Invoke(this, e);
			}
		}
		protected virtual void OnDropDownClosing(RoutedPropertyChangingEventArgs<bool> e)
		{
			RoutedPropertyChangingEventHandler<bool> dropDownClosing = this.DropDownClosing;
			if (dropDownClosing != null)
			{
				dropDownClosing(this, e);
			}
		}
		protected virtual void OnDropDownClosed(RoutedPropertyChangedEventArgs<bool> e)
		{
			RoutedPropertyChangedEventHandler<bool> dropDownClosed = this.DropDownClosed;
			if (dropDownClosed != null)
			{
				dropDownClosed.Invoke(this, e);
			}
		}
		private string FormatValue(object value, bool clearDataContext)
		{
			string result = this.FormatValue(value);
			if (clearDataContext && this._valueBindingEvaluator != null)
			{
				this._valueBindingEvaluator.ClearDataContext();
			}
			return result;
		}
		protected virtual string FormatValue(object value)
		{
			if (this._valueBindingEvaluator != null)
			{
				return this._valueBindingEvaluator.GetDynamicValue(value) ?? string.Empty;
			}
			if (value != null)
			{
				return value.ToString();
			}
			return string.Empty;
		}
		protected virtual void OnTextChanged(RoutedEventArgs e)
		{
			RoutedEventHandler textChanged = this.TextChanged;
			if (textChanged != null)
			{
				textChanged.Invoke(this, e);
			}
		}
		private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e)
		{
			this.TextUpdated(this._text.get_Text(), true);
		}
		private void OnTextBoxSelectionChanged(object sender, RoutedEventArgs e)
		{
			if (!this._ignoreTextSelectionChange && !this._inputtingText)
			{
				this._textSelectionStart = this._text.get_SelectionStart();
				return;
			}
		}
		private void OnUIElementKeyDown(object sender, KeyEventArgs e)
		{
			this._inputtingText = true;
		}
		private void OnUIElementKeyUp(object sender, KeyEventArgs e)
		{
			this._inputtingText = false;
		}
		private void UpdateTextValue(string value)
		{
			this.UpdateTextValue(value, default(bool?));
		}
		private void UpdateTextValue(string value, bool? userInitiated)
		{
			if (userInitiated.get_HasValue())
			{
				bool? flag = userInitiated;
				if (!flag.GetValueOrDefault() || !flag.get_HasValue())
				{
					goto IL_4E;
				}
			}
			if (this.Text != value)
			{
				this._ignoreTextPropertyChange++;
				this.Text = value;
				this.OnTextChanged(new RoutedEventArgs());
			}
			IL_4E:
			if (userInitiated.get_HasValue())
			{
				bool? flag2 = userInitiated;
				if (flag2.GetValueOrDefault() || !flag2.get_HasValue())
				{
					return;
				}
			}
			if (this.TextBox != null && this.TextBox.get_Text() != value)
			{
				this._ignoreTextPropertyChange++;
				this.TextBox.set_Text(value ?? string.Empty);
				if (this.Text == value || this.Text == null)
				{
					this.OnTextChanged(new RoutedEventArgs());
				}
			}
		}
		private void TextUpdated(string newText, bool userInitiated)
		{
			if (this._ignoreTextPropertyChange > 0)
			{
				this._ignoreTextPropertyChange--;
				return;
			}
			if (newText == null)
			{
				newText = string.Empty;
			}
			if (this.IsTextCompletionEnabled && this.TextBox != null && this.TextBox.get_SelectionLength() > 0 && this.TextBox.get_SelectionStart() != this.TextBox.get_Text().get_Length())
			{
				return;
			}
			bool flag = newText.get_Length() >= this.MinimumPrefixLength && this.MinimumPrefixLength >= 0;
			this._userCalledPopulate = (flag && userInitiated);
			this.UpdateTextValue(newText, new bool?(userInitiated));
			if (!flag)
			{
				this.SearchText = string.Empty;
				if (this.SelectedItem != null)
				{
					this._skipSelectedItemTextUpdate = true;
				}
				this.SelectedItem = null;
				if (this.IsDropDownOpen)
				{
					this.IsDropDownOpen = false;
				}
				return;
			}
			this._ignoreTextSelectionChange = true;
			if (this._delayTimer != null)
			{
				this._delayTimer.Start();
				return;
			}
			this.PopulateDropDown(this, EventArgs.Empty);
		}
		public void PopulateComplete()
		{
			this.RefreshView();
			PopulatedEventArgs e = new PopulatedEventArgs(new ReadOnlyCollection<object>(this._view));
			this.OnPopulated(e);
			if (this.SelectionAdapter != null && this.SelectionAdapter.ItemsSource != this._view)
			{
				this.SelectionAdapter.ItemsSource = this._view;
			}
			bool isDropDownOpen;
			if ((isDropDownOpen = (this._userCalledPopulate && this._view.get_Count() > 0)) != this.IsDropDownOpen)
			{
				this._ignorePropertyChange = true;
				this.IsDropDownOpen = isDropDownOpen;
			}
			if (this.IsDropDownOpen)
			{
				this.OpeningDropDown(false);
				if (this.DropDownPopup != null)
				{
					this.DropDownPopup.Arrange(default(Size?));
				}
			}
			else
			{
				this.ClosingDropDown(true);
			}
			this.UpdateTextCompletion(this._userCalledPopulate);
		}
		private void UpdateTextCompletion(bool userInitiated)
		{
			object obj = null;
			string text = this.Text;
			if (this._view.get_Count() > 0)
			{
				if (this.IsTextCompletionEnabled && this.TextBox != null && userInitiated)
				{
					int length = this.TextBox.get_Text().get_Length();
					int selectionStart = this.TextBox.get_SelectionStart();
					if (selectionStart == text.get_Length() && selectionStart > this._textSelectionStart)
					{
						object obj2 = (this.FilterMode == AutoCompleteFilterMode.StartsWith || this.FilterMode == AutoCompleteFilterMode.StartsWithCaseSensitive) ? this._view.get_Item(0) : this.TryGetMatch(text, this._view, AutoCompleteSearch.GetFilter(AutoCompleteFilterMode.StartsWith));
						if (obj2 != null)
						{
							obj = obj2;
							string text2 = this.FormatValue(obj2, true);
							int num = Math.Min(text2.get_Length(), this.Text.get_Length());
							if (AutoCompleteSearch.Equals(this.Text.Substring(0, num), text2.Substring(0, num)))
							{
								this.UpdateTextValue(text2);
								this.TextBox.set_SelectionStart(length);
								this.TextBox.set_SelectionLength(text2.get_Length() - length);
							}
						}
					}
				}
				else
				{
					obj = this.TryGetMatch(text, this._view, AutoCompleteSearch.GetFilter(AutoCompleteFilterMode.EqualsCaseSensitive));
				}
			}
			if (this.SelectedItem != obj)
			{
				this._skipSelectedItemTextUpdate = true;
			}
			this.SelectedItem = obj;
			if (this._ignoreTextSelectionChange)
			{
				this._ignoreTextSelectionChange = false;
				if (this.TextBox != null && !this._inputtingText)
				{
					this._textSelectionStart = this.TextBox.get_SelectionStart();
				}
			}
		}
		private object TryGetMatch(string searchText, ObservableCollection<object> view, AutoCompleteFilterPredicate<string> predicate)
		{
			if (view != null && view.get_Count() > 0)
			{
				object result;
				using (IEnumerator<object> enumerator = view.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						object current = enumerator.get_Current();
						if (predicate(searchText, this.FormatValue(current)))
						{
							result = current;
							return result;
						}
					}
					goto IL_47;
				}
				return result;
			}
			IL_47:
			return null;
		}
		private void ClearView()
		{
			if (this._view == null)
			{
				this._view = new ObservableCollection<object>();
				return;
			}
			this._view.Clear();
		}
		private void RefreshView()
		{
			if (this._items == null)
			{
				this.ClearView();
				return;
			}
			string search = this.Text ?? string.Empty;
			bool flag = this.TextFilter != null;
			bool flag2 = this.FilterMode == AutoCompleteFilterMode.Custom && this.TextFilter == null;
			int num = 0;
			int num2 = this._view.get_Count();
			List<object> items = this._items;
			using (List<object>.Enumerator enumerator = items.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					object current = enumerator.get_Current();
					bool flag3;
					if (!(flag3 = (!flag && !flag2)))
					{
						flag3 = (flag ? this.TextFilter(search, this.FormatValue(current)) : this.ItemFilter(search, current));
					}
					if (num2 > num && flag3 && this._view.get_Item(num) == current)
					{
						num++;
					}
					else
					{
						if (flag3)
						{
							if (num2 > num && this._view.get_Item(num) != current)
							{
								this._view.RemoveAt(num);
								this._view.Insert(num, current);
								num++;
							}
							else
							{
								if (num == num2)
								{
									this._view.Add(current);
								}
								else
								{
									this._view.Insert(num, current);
								}
								num++;
								num2++;
							}
						}
						else
						{
							if (num2 > num && this._view.get_Item(num) == current)
							{
								this._view.RemoveAt(num);
								num2--;
							}
						}
					}
				}
			}
			if (this._valueBindingEvaluator != null)
			{
				this._valueBindingEvaluator.ClearDataContext();
			}
		}
		private void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
		{
			INotifyCollectionChanged notifyCollectionChanged = oldValue as INotifyCollectionChanged;
			if (notifyCollectionChanged != null && this._collectionChangedWeakEventListener != null)
			{
				this._collectionChangedWeakEventListener.Detach();
				this._collectionChangedWeakEventListener = null;
			}
			INotifyCollectionChanged newValueINotifyCollectionChanged = newValue as INotifyCollectionChanged;
			if (newValueINotifyCollectionChanged != null)
			{
				this._collectionChangedWeakEventListener = new WeakEventListener<AutoCompleteBox, object, NotifyCollectionChangedEventArgs>(this);
				this._collectionChangedWeakEventListener.OnEventAction = delegate(AutoCompleteBox instance, object source, NotifyCollectionChangedEventArgs eventArgs)
				{
					instance.ItemsSourceCollectionChanged(source, eventArgs);
				};
				this._collectionChangedWeakEventListener.OnDetachAction = delegate(WeakEventListener<AutoCompleteBox, object, NotifyCollectionChangedEventArgs> weakEventListener)
				{
					newValueINotifyCollectionChanged.remove_CollectionChanged(new NotifyCollectionChangedEventHandler(weakEventListener.OnEvent));
				};
				newValueINotifyCollectionChanged.add_CollectionChanged(new NotifyCollectionChangedEventHandler(this._collectionChangedWeakEventListener.OnEvent));
			}
			this._items = ((newValue == null) ? null : new List<object>(Enumerable.ToList<object>(Enumerable.Cast<object>(newValue))));
			this.ClearView();
			if (this.SelectionAdapter != null && this.SelectionAdapter.ItemsSource != this._view)
			{
				this.SelectionAdapter.ItemsSource = this._view;
			}
			if (this.IsDropDownOpen)
			{
				this.RefreshView();
			}
		}
		private void ItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
		{
			if (e.get_Action() == 1 && e.get_OldItems() != null)
			{
				for (int i = 0; i < e.get_OldItems().get_Count(); i++)
				{
					this._items.RemoveAt(e.get_OldStartingIndex());
				}
			}
			if (e.get_Action() == null && e.get_NewItems() != null && this._items.get_Count() >= e.get_NewStartingIndex())
			{
				for (int j = 0; j < e.get_NewItems().get_Count(); j++)
				{
					this._items.Insert(e.get_NewStartingIndex() + j, e.get_NewItems().get_Item(j));
				}
			}
			if (e.get_Action() == 2 && e.get_NewItems() != null && e.get_OldItems() != null)
			{
				for (int k = 0; k < e.get_NewItems().get_Count(); k++)
				{
					this._items.set_Item(e.get_NewStartingIndex(), e.get_NewItems().get_Item(k));
				}
			}
			if (e.get_Action() == 1 || e.get_Action() == 2)
			{
				for (int l = 0; l < e.get_OldItems().get_Count(); l++)
				{
					this._view.Remove(e.get_OldItems().get_Item(l));
				}
			}
			if (e.get_Action() == 4)
			{
				this.ClearView();
				if (this.ItemsSource != null)
				{
					this._items = new List<object>(Enumerable.ToList<object>(Enumerable.Cast<object>(this.ItemsSource)));
				}
			}
			this.RefreshView();
		}
		private void OnAdapterSelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			this.SelectedItem = this._adapter.SelectedItem;
		}
		private void OnAdapterSelectionComplete(object sender, RoutedEventArgs e)
		{
			this.IsDropDownOpen = false;
			this.UpdateTextCompletion(false);
			if (this.TextBox != null)
			{
				this.TextBox.Select(this.TextBox.get_Text().get_Length(), 0);
				this.TextBox.Focus();
			}
		}
		private void OnAdapterSelectionCanceled(object sender, RoutedEventArgs e)
		{
			this.UpdateTextValue(this.SearchText);
			this.UpdateTextCompletion(false);
		}
		private void OnMaxDropDownHeightChanged(double newValue)
		{
			if (this.DropDownPopup != null)
			{
				this.DropDownPopup.MaxDropDownHeight = newValue;
				this.DropDownPopup.Arrange(default(Size?));
			}
			this.UpdateVisualState(true);
		}
		private void OpenDropDown(bool oldValue, bool newValue)
		{
			if (this.DropDownPopup != null)
			{
				this.DropDownPopup.IsOpen = true;
			}
			this._popupHasOpened = true;
			this.OnDropDownOpened(new RoutedPropertyChangedEventArgs<bool>(oldValue, newValue));
		}
		private void CloseDropDown(bool oldValue, bool newValue)
		{
			if (this._popupHasOpened)
			{
				if (this.SelectionAdapter != null)
				{
					this.SelectionAdapter.SelectedItem = null;
				}
				if (this.DropDownPopup != null)
				{
					this.DropDownPopup.IsOpen = false;
				}
				this.OnDropDownClosed(new RoutedPropertyChangedEventArgs<bool>(oldValue, newValue));
			}
		}
		protected override void OnKeyDown(KeyEventArgs e)
		{
			if (e == null)
			{
				throw new ArgumentNullException("e");
			}
			base.OnKeyDown(e);
			if (e.get_Handled() || !base.get_IsEnabled())
			{
				return;
			}
			if (this.IsDropDownOpen)
			{
				if (this.SelectionAdapter != null)
				{
					this.SelectionAdapter.HandleKeyDown(e);
					if (e.get_Handled())
					{
						return;
					}
				}
				if (e.get_Key() == 8)
				{
					this.OnAdapterSelectionCanceled(this, new RoutedEventArgs());
					e.set_Handled(true);
				}
			}
			else
			{
				if (e.get_Key() == 17)
				{
					this.IsDropDownOpen = true;
					e.set_Handled(true);
				}
			}
			Key key = e.get_Key();
			if (key == 3)
			{
				this.OnAdapterSelectionComplete(this, new RoutedEventArgs());
				e.set_Handled(true);
				return;
			}
			if (key != 59)
			{
				return;
			}
			this.IsDropDownOpen = !this.IsDropDownOpen;
			e.set_Handled(true);
		}
		void IUpdateVisualState.UpdateVisualState(bool useTransitions)
		{
			this.UpdateVisualState(useTransitions);
		}
		internal virtual void UpdateVisualState(bool useTransitions)
		{
			VisualStateManager.GoToState(this, this.IsDropDownOpen ? "PopupOpened" : "PopupClosed", useTransitions);
			this.Interaction.UpdateVisualStateBase(useTransitions);
		}
	}
}
